package org.example.deep.utils.jwt;

/**
 * @author jianxin.wei
 * @description
 * @date 2024/9/13 10:48
 */

import cn.hutool.json.JSONObject;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTPayload;
import cn.hutool.jwt.JWTUtil;
import cn.hutool.jwt.signers.JWTSignerUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.HashMap;
import java.util.Map;
@Component
@Slf4j
public class JWTUtils {
    //密钥
    private static final String SECRET = "!Oh12345HA$666";
    //token默认过期时间（30分钟）
    private static final long EXPIRATION_TIME = 1800000;

    public static String generateToken(Map<String, Object> body) {
        if (body == null || body.isEmpty()) {
            return null;
        }
        Map<String, Object> hearders = new HashMap<>();
        hearders.put("createDate", LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
        return JWTUtil.createToken(hearders, body, SECRET.getBytes());
    }

    public static String generateTokenExpired(Map<String, Object> body) {
        return generateTokenExpired(body, EXPIRATION_TIME);
    }

    public static String generateTokenExpired(Map<String, Object> body, long milliSecond) {
        if (body == null || body.isEmpty()) {
            return null;
        }
        long signTime = LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
        long expireTime = signTime + milliSecond;
        body.put("signTime", signTime);
        body.put("expireTime", expireTime);

        Map<String, Object> hearders = new HashMap<>();
        hearders.put("createDate", signTime);
        return JWTUtil.createToken(hearders, body, SECRET.getBytes());
    }


    /**
     * 验证token
     *
     * @param token token
     * @return int 0:失败 1:成功
     */
    public static int verify(String token) {
        if (token == null) {
            return 0;
        }
        try {
            JWT jwt = JWTUtil.parseToken(token);
            boolean verify = jwt.verify(JWTSignerUtil.hs256(SECRET.getBytes()));
            if (verify) {
                return 1;
            }
        } catch (Exception e) {
            log.info("token验证异常", e);
        }
        return 0;
    }

    /**
     * 验证token
     *
     * @param token token
     * @return int 0:失败 1:成功 2：过期
     */
    public static int verifyExpired(String token) {
        if (token == null) {
            return 0;
        }
        try {
            JWT jwt = JWTUtil.parseToken(token);
            boolean verify = jwt.verify(JWTSignerUtil.hs256(SECRET.getBytes()));
            if (verify) {
                long expireTime = (long) jwt.getPayload("expireTime");
                LocalDateTime expireDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(expireTime), ZoneId.systemDefault());
                if (LocalDateTime.now().isBefore(expireDate)) {
                    return 1;
                } else {
                    return 2;
                }
            }
        } catch (Exception e) {
            log.info("token验证异常", e);
        }
        return 0;
    }


    /**
     * 解析token
     *
     * @param token token
     * @return map
     */
    public static Map parseToken(String token) {
        if (token == null) {
            return null;
        }
        try {
            int verify = verify(token);
            if (verify == 1) {
                JWT jwt = JWTUtil.parseToken(token);
                JWTPayload payload = jwt.getPayload();
                JSONObject claimsJson = payload.getClaimsJson();
                return claimsJson.toBean(Map.class);
            }
        } catch (Exception e) {
            log.info("token解析异常", e);
        }
        return null;
    }

    /**
     * 解析token
     *
     * @param token token
     * @return map
     */
    public static Map parseTokenExpired(String token) {
        if (token == null) {
            return null;
        }
        try {
            int verify = verifyExpired(token);
            if (verify == 1) {
                JWT jwt = JWTUtil.parseToken(token);
                JWTPayload payload = jwt.getPayload();
                JSONObject claimsJson = payload.getClaimsJson();
                claimsJson.remove("signTime");
                claimsJson.remove("expireTime");
                return claimsJson.toBean(Map.class);
            }
        } catch (Exception e) {
            log.info("token解析异常", e);
        }
        return null;
    }

}

